﻿using System.Collections.Generic;
using NHibernate;
using NHibernate.Criterion;
using Neturion.Dados;
using Neturion.IRepositorios;

namespace Neturion.Repositorios
{
    public class RepositorioMotivoProtocolo : IRepositorioMotivoProtocolo
    {
        public MotivoProtocolo Inserir(MotivoProtocolo motivoProtocolo)
        {
            motivoProtocolo.FimVigencia = motivoProtocolo.FimVigencia.HasValue
                                           ? motivoProtocolo.FimVigencia.GetValueOrDefault().Date
                                           : motivoProtocolo.FimVigencia;
            motivoProtocolo.InicioVigencia = motivoProtocolo.InicioVigencia.HasValue
                                           ? motivoProtocolo.InicioVigencia.GetValueOrDefault().Date
                                           : motivoProtocolo.InicioVigencia;

            GerenciadorBDConfigs.Instance.SessaoAtual().Save(motivoProtocolo);
            return motivoProtocolo;
        }

        public MotivoProtocolo Atualizar(MotivoProtocolo motivoProtocolo)
        {
            MotivoProtocolo tmpMotivoProtocolo = ObterPorId(motivoProtocolo.MotivoProtocoloId);
            // Atribuicao dos valores do objeto da memoria para o objeto obtido no banco de dados
            tmpMotivoProtocolo.Codigo = motivoProtocolo.Codigo;
            tmpMotivoProtocolo.Descricao = motivoProtocolo.Descricao;
            tmpMotivoProtocolo.FimVigencia = motivoProtocolo.FimVigencia.HasValue
                                           ? motivoProtocolo.FimVigencia.GetValueOrDefault().Date
                                           : motivoProtocolo.FimVigencia;
            tmpMotivoProtocolo.InicioVigencia = motivoProtocolo.InicioVigencia.HasValue
                                           ? motivoProtocolo.InicioVigencia.GetValueOrDefault().Date
                                           : motivoProtocolo.InicioVigencia;
            tmpMotivoProtocolo.NeturionLog = motivoProtocolo.NeturionLog;
            tmpMotivoProtocolo.TipoMotivo = motivoProtocolo.TipoMotivo;

            tmpMotivoProtocolo.ListaAssuntos.Clear();
            foreach (Assunto assunto in motivoProtocolo.ListaAssuntos)
            {
                tmpMotivoProtocolo.AdicionarAssunto(assunto);
            }

            GerenciadorBDConfigs.Instance.SessaoAtual().Merge(tmpMotivoProtocolo);
            return tmpMotivoProtocolo;
        }

        public void Excluir(MotivoProtocolo motivoProtocolo)
        {
            GerenciadorBDConfigs.Instance.SessaoAtual().Delete(motivoProtocolo);
        }

        public IList<MotivoProtocolo> ObterTodos()
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(MotivoProtocolo));
            return criteria.List<MotivoProtocolo>() as List<MotivoProtocolo>;
        }

        public MotivoProtocolo ObterPorId(int id)
        {
            return GerenciadorBDConfigs.Instance.SessaoAtual().Get<MotivoProtocolo>(id);
        }

        public MotivoProtocolo ObterPorCodigo(string codigo)
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(MotivoProtocolo))
                .Add(Restrictions.Eq("Codigo",codigo));
            return criteria.UniqueResult<MotivoProtocolo>();
        }

        public IList<MotivoProtocolo> ObterPorTipoMotivo(TipoProtocolo tipoMotivo)
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(MotivoProtocolo))
                .Add(Restrictions.Eq("TipoMotivo", tipoMotivo));
            return criteria.List<MotivoProtocolo>() as List<MotivoProtocolo>;
        }

        public IList<MotivoProtocolo> ObterPorDescricao(string descricao)
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(MotivoProtocolo))
                .Add(Restrictions.Eq("Descricao", descricao));
            return criteria.List<MotivoProtocolo>() as List<MotivoProtocolo>;
        }

        public int ObterUltimoIdCodigoInteiro()
        {
            string[] literal = new string[] 
                {"a","b","c","d","e","f","g","h","i","j"
                ,"l","m","n","o","p","q","r","s","t","u","v","x","z","y"
                ,"w"};

            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(MotivoProtocolo)).SetMaxResults(1);

            for (int i = 0; i <= literal.Length - 1; i++)
            {
                criteria.Add(Restrictions.Not(Restrictions.Like("Codigo", literal[i], MatchMode.Anywhere)));
            }

            criteria.AddOrder(Order.Desc("MotivoProtocoloId"));


            MotivoProtocolo motivoProtocolo = criteria.UniqueResult<MotivoProtocolo>();
            int ultimoCodigo = motivoProtocolo != null ? motivoProtocolo.MotivoProtocoloId : 0;

            return ultimoCodigo;
        }

        public IList<MotivoProtocolo> ObterTodos(int inicio, int quantidade, int quantidadeMinima, string codigo, string descricao, TipoMotivo tipoMotivo, System.DateTime? inicioVigenciaDe, System.DateTime? inicioVigenciaAte, System.DateTime? fimVigenciaDe, System.DateTime? fimVigenciaAte)
        {
            if (quantidade.Equals(0))
            {
                quantidade = quantidadeMinima;
            }

            IList<MotivoProtocolo> list;
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(MotivoProtocolo))
               .SetFirstResult(inicio).SetMaxResults(quantidade);

            if (!string.IsNullOrEmpty(codigo))
            {
                criteria.Add(Restrictions.Eq("Codigo", codigo));
            }

            if (!string.IsNullOrEmpty(descricao))
            {
                criteria.Add(Restrictions.Like("Descricao", descricao, MatchMode.Anywhere));
            }

            if (tipoMotivo != null)
            {
                criteria.Add(Restrictions.Eq("TipoMotivo", tipoMotivo));
            }

            if (inicioVigenciaDe.HasValue)
            {
                criteria.Add(inicioVigenciaAte.HasValue
                    ? Restrictions.Between("InicioVigencia", inicioVigenciaDe.Value.Date, inicioVigenciaAte.Value.Date)
                    : Restrictions.Eq("InicioVigencia", inicioVigenciaDe.Value.Date));
            }

            if (fimVigenciaDe.HasValue)
            {
                criteria.Add(fimVigenciaAte.HasValue
                    ? Restrictions.Between("FimVigencia", fimVigenciaDe.Value.Date, fimVigenciaAte.Value.Date)
                    : Restrictions.Eq("FimVigencia", fimVigenciaDe.Value.Date));
            }

            list = criteria.List<MotivoProtocolo>() as List<MotivoProtocolo>;

            return list;
        }
    }
}